package com.group1.bookmanagement.dao.impl;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;

import com.group1.bookmanagement.dao.BaseDao;

@Repository("baseDao")
public class BaseDaoImpl<T> implements BaseDao<T> {
	
	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;
	
	@Override
	public Session openSession() {
		return sessionFactory.openSession();
	}
	
	@Override
	public Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}

	@Override
	public Serializable save(T t) {
		return getCurrentSession().save(t);
	}

	@Override
	public void delete(T t) {
		getCurrentSession().delete(t);
	}

	@Override
	public void update(T t) {
		getCurrentSession().update(t);
	}

	@Override
	public void saveOrUpdate(T t) {
		getCurrentSession().saveOrUpdate(t);
	}

	@Override
	public void merge(T t) {
		getCurrentSession().merge(t);
	}
	
	@Override
	public T get(Class<T> clazz, Serializable id) {
		return getCurrentSession().get(clazz, id);
	}

	@Override
	public List<T> list(Class<T> clazz) {
		String hql = "from " + clazz.getName();
		return getCurrentSession().createQuery(hql).list();
	}
	
	@Override
	public Object find(String hql) {
		return getCurrentSession().createQuery(hql).uniqueResult();
	}
	
	@Override
	public Object find(String hql, Object... param) {
		if (param == null && param.length == 0) {
			return null;
		}
		
		Query query = getCurrentSession().createQuery(hql);
		for(int i = 0; i < param.length; i++) {
			query.setParameter(i, param[i]);
		}
		
		return query.uniqueResult();
	}
	
	@Override
	public List<T> findAll(String hql) {
		return getCurrentSession().createQuery(hql).list();
	}
	
	@Override
	public List<T> findAll(String hql, Object... param) {
		if (param == null && param.length == 0) {
			return null;
		}
		
		Query query = getCurrentSession().createQuery(hql);
		for(int i = 0; i < param.length; i++) {
			query.setParameter(i, param[i]);
		}
		
		return query.list();
	}

	@Override
	public List<T> findAll(String hql, int offset, int limit) {
		Query query = getCurrentSession().createQuery(hql);
		query.setFirstResult(offset);
		query.setMaxResults(limit);
		return query.list();
	}
	
	@Override
	public List<T> findAll(String hql, int offset, int limit, Object... param) {
		if (param == null && param.length == 0) {
			return null;
		}
		
		Query query = getCurrentSession().createQuery(hql);
		for(int i = 0; i < param.length; i++) {
			query.setParameter(i, param[i]);
		}
		query.setFirstResult(offset);
		query.setMaxResults(limit);
		
		return query.list();
	}
	
}
